using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;
using System.Windows.Forms;

using SBPweb.Themes.Windows.Skins;
using SBPweb.Themes.Windows;

namespace SBPweb.Controls.Windows.Form
{
	/// <summary>
	/// Class of FormButtonClose
	/// </summary>
	[ToolboxItem(false)]
	public partial class FormButtonClose : System.Windows.Forms.Button, ISkinnable
	{
		#region Private members

		private bool mUseDefaultSkin;
		private Skin mSkin;
		private Margin mSizingMargin;
		private MouseEventState mMState = MouseEventState.None;

		#endregion

		#region Constructor logic

		public FormButtonClose()
		{
			InitializeComponent();
			InitializeMargins();
			mSizingMargin = new Margin();
			SetStyle();
			RegisterEventHandlers();
		}

		public FormButtonClose(Skin skin)
		{
			mSkin = skin;
			InitializeMargins();
			SetStyle();
			RegisterEventHandlers();
		}

		public FormButtonClose(IContainer container)
		{
			container.Add(this);
			InitializeComponent();
			InitializeMargins();
			mSizingMargin = new Margin();
			SetStyle();
			RegisterEventHandlers();
		}

		private void SetStyle()
		{
			base.SetStyle(ControlStyles.ResizeRedraw | ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.SupportsTransparentBackColor, true);
		}

		private void RegisterEventHandlers()
		{
			this.MouseEnter += new EventHandler(this_MouseEnter);
			this.MouseLeave += new EventHandler(this_MouseLeave);
			this.MouseDown += new MouseEventHandler(this_MouseDown);
			this.MouseUp += new MouseEventHandler(this_MouseUp);
			this.MouseHover += new EventHandler(this_MouseHover);
			DefaultLookAndFeel.OnSkinChanged += new EventHandler(DefaultLookAndFeel_OnSkinChanged);
		}

		private void InitializeMargins()
		{
			if (Skin == null)
				mSizingMargin = new Margin();
			else
				mSizingMargin = new Margin(Skin.SelectSingleNode("Elements/FormButtonClose/Image/SizingMargins"));
		}

		#endregion

		#region Custom draw

		protected override void OnPaint(PaintEventArgs e)
		{
			if (Skin == null)
			{
				base.OnPaint(e);

				return;
			}

			base.OnPaintBackground(e);

			int imgCurrent = 0;

			switch (mMState)
			{
				default:
				case MouseEventState.None:
					if (this.Enabled)
					{
						imgCurrent = 0;
					}
					else
					{
						imgCurrent = 3;
					}
					break;
				case MouseEventState.OnHover:
					imgCurrent = 1;
					break;
				case MouseEventState.OnDown:
					if (this.Enabled)
					{
						imgCurrent = 2;
					}
					else
					{
						imgCurrent = 4;
					}
					break;
			}

			#region Window parts
			Rectangle tLT = new Rectangle(this.ClientRectangle.Left, this.ClientRectangle.Top, Skin.CachedProperties.FormButtonCloseSizingMargin.Left, Skin.CachedProperties.FormButtonCloseSizingMargin.Top);
			Rectangle tT = new Rectangle(this.ClientRectangle.Left + Skin.CachedProperties.FormButtonCloseSizingMargin.Left, this.ClientRectangle.Top, this.ClientRectangle.Width - Skin.CachedProperties.FormButtonCloseSizingMargin.Horizontal, Skin.CachedProperties.FormButtonCloseSizingMargin.Top);
			Rectangle tRT = new Rectangle(this.ClientRectangle.Right - Skin.CachedProperties.FormButtonCloseSizingMargin.Right, this.ClientRectangle.Top, Skin.CachedProperties.FormButtonCloseSizingMargin.Right, Skin.CachedProperties.FormButtonCloseSizingMargin.Top);
			Rectangle tLM = new Rectangle(this.ClientRectangle.Left, this.ClientRectangle.Top + Skin.CachedProperties.FormButtonCloseSizingMargin.Top, Skin.CachedProperties.FormButtonCloseSizingMargin.Left, this.ClientRectangle.Height - Skin.CachedProperties.FormButtonCloseSizingMargin.Vertical);
			Rectangle tM = new Rectangle(this.ClientRectangle.Left + Skin.CachedProperties.FormButtonCloseSizingMargin.Left, this.ClientRectangle.Top + Skin.CachedProperties.FormButtonCloseSizingMargin.Top, this.ClientRectangle.Width - Skin.CachedProperties.FormButtonCloseSizingMargin.Horizontal, this.ClientRectangle.Height - Skin.CachedProperties.FormButtonCloseSizingMargin.Vertical);
			Rectangle tRM = new Rectangle(this.ClientRectangle.Right - Skin.CachedProperties.FormButtonCloseSizingMargin.Right, this.ClientRectangle.Top + Skin.CachedProperties.FormButtonCloseSizingMargin.Top, Skin.CachedProperties.FormButtonCloseSizingMargin.Right, this.ClientRectangle.Height - Skin.CachedProperties.FormButtonCloseSizingMargin.Vertical);
			Rectangle tLB = new Rectangle(this.ClientRectangle.Left, this.ClientRectangle.Bottom - Skin.CachedProperties.FormButtonCloseSizingMargin.Bottom, Skin.CachedProperties.FormButtonCloseSizingMargin.Left, Skin.CachedProperties.FormButtonCloseSizingMargin.Bottom);
			Rectangle tB = new Rectangle(this.ClientRectangle.Left + Skin.CachedProperties.FormButtonCloseSizingMargin.Left, this.ClientRectangle.Bottom - Skin.CachedProperties.FormButtonCloseSizingMargin.Bottom, this.ClientRectangle.Width - Skin.CachedProperties.FormButtonCloseSizingMargin.Horizontal, Skin.CachedProperties.FormButtonCloseSizingMargin.Bottom);
			Rectangle tRB = new Rectangle(this.ClientRectangle.Right - Skin.CachedProperties.FormButtonCloseSizingMargin.Right, this.ClientRectangle.Bottom - Skin.CachedProperties.FormButtonCloseSizingMargin.Bottom, Skin.CachedProperties.FormButtonCloseSizingMargin.Right, Skin.CachedProperties.FormButtonCloseSizingMargin.Bottom);
			#endregion

			#region Drawing

			Image iLT = Skin.CachedProperties.FormButtonCloseImageLT[imgCurrent];
			Image iT = Skin.CachedProperties.FormButtonCloseImageT[imgCurrent];
			Image iRT = Skin.CachedProperties.FormButtonCloseImageRT[imgCurrent];
			Image iLM = Skin.CachedProperties.FormButtonCloseImageLM[imgCurrent];
			Image iM = Skin.CachedProperties.FormButtonCloseImageM[imgCurrent];
			Image iRM = Skin.CachedProperties.FormButtonCloseImageRM[imgCurrent];
			Image iLB = Skin.CachedProperties.FormButtonCloseImageLB[imgCurrent];
			Image iB = Skin.CachedProperties.FormButtonCloseImageB[imgCurrent];
			Image iRB = Skin.CachedProperties.FormButtonCloseImageRB[imgCurrent];

			e.Graphics.PixelOffsetMode = PixelOffsetMode.None;

			if (Skin.CachedProperties.FormButtonCloseSizingMargin.Left != 0 && Skin.CachedProperties.FormButtonCloseSizingMargin.Top != 0)
				e.Graphics.DrawImage(iLT, tLT, new Rectangle(1, 1, iLT.Width - 2, iLT.Height - 2), GraphicsUnit.Pixel);
			if (Skin.CachedProperties.FormButtonCloseSizingMargin.Top != 0)
				e.Graphics.DrawImage(iT, tT, new Rectangle(1, 1, iT.Width - 2, iT.Height - 2), GraphicsUnit.Pixel);
			if (Skin.CachedProperties.FormButtonCloseSizingMargin.Right != 0 && Skin.CachedProperties.FormButtonCloseSizingMargin.Top != 0)
				e.Graphics.DrawImage(iRT, tRT, new Rectangle(1, 1, iRT.Width - 2, iRT.Height - 2), GraphicsUnit.Pixel);
			if (Skin.CachedProperties.FormButtonCloseSizingMargin.Left != 0)
				e.Graphics.DrawImage(iLM, tLM, new Rectangle(1, 1, iLM.Width - 2, iLM.Height - 2), GraphicsUnit.Pixel);
			e.Graphics.DrawImage(iM, tM, new Rectangle(1, 1, iM.Width - 2, iM.Height - 2), GraphicsUnit.Pixel);
			if (Skin.CachedProperties.FormButtonCloseSizingMargin.Right != 0)
				e.Graphics.DrawImage(iRM, tRM, new Rectangle(1, 1, iRM.Width - 2, iRM.Height - 2), GraphicsUnit.Pixel);
			if (Skin.CachedProperties.FormButtonCloseSizingMargin.Left != 0 && Skin.CachedProperties.FormButtonCloseSizingMargin.Bottom != 0)
				e.Graphics.DrawImage(iLB, tLB, new Rectangle(1, 1, iLB.Width - 2, iLB.Height - 2), GraphicsUnit.Pixel);
			if (Skin.CachedProperties.FormButtonCloseSizingMargin.Bottom != 0)
				e.Graphics.DrawImage(iB, tB, new Rectangle(1, 1, iB.Width - 2, iB.Height - 2), GraphicsUnit.Pixel);
			if (Skin.CachedProperties.FormButtonCloseSizingMargin.Right != 0 && Skin.CachedProperties.FormButtonCloseSizingMargin.Bottom != 0)
				e.Graphics.DrawImage(iRB, tRB, new Rectangle(1, 1, iRB.Width - 2, iRB.Height - 2), GraphicsUnit.Pixel);

			DrawImage(e);
			
			#endregion
		}

		private void DrawImage(PaintEventArgs e)
		{
			int imgCurrent = 0;

			switch (mMState)
			{
				default:
				case MouseEventState.None:
					if (this.Enabled)
					{
						imgCurrent = 0;
					}
					else
					{
						imgCurrent = 3;
					}
					break;
				case MouseEventState.OnHover:
					imgCurrent = 1;
					break;
				case MouseEventState.OnDown:
					if (this.Enabled)
					{
						imgCurrent = 2;
					}
					else
					{
						imgCurrent = 4;
					}
					break;
			}

			Rectangle tM = new Rectangle(((this.ClientRectangle.Left + this.ClientRectangle.Right) / 2 - Skin.CachedProperties.FormButtonCloseGlyphWidth / 2), ((this.ClientRectangle.Bottom + this.ClientRectangle.Top) / 2 - Skin.CachedProperties.FormButtonCloseGlyphHeight / 2), Skin.CachedProperties.FormButtonCloseGlyphWidth, Skin.CachedProperties.FormButtonCloseGlyphHeight);
			Image iM = Skin.CachedProperties.FormButtonCloseGlyphImageM[imgCurrent];
			e.Graphics.DrawImage(iM, tM, new Rectangle(1, 1, iM.Width-2, iM.Height-2), GraphicsUnit.Pixel);
			
			this.MinimumSize = new System.Drawing.Size(Skin.CachedProperties.FormButtonCloseGlyphWidth, Skin.CachedProperties.FormButtonCloseGlyphHeight);
		}

		#endregion

		#region Events

		void DefaultLookAndFeel_OnSkinChanged(object sender, EventArgs e)
		{
			InitializeMargins();
			SetStyle();
			Invalidate(true);
		}

		void this_MouseEnter(object sender, EventArgs e)
		{
			mMState = MouseEventState.OnHover;
			this.Invalidate();
		}

		void this_MouseUp(object sender, MouseEventArgs e)
		{
			if (e.X < 0 || e.X > this.Width || e.Y < 0 || e.Y > this.Height)
			{
				mMState = MouseEventState.None;
			}
			else
			{
				mMState = MouseEventState.OnHover;
			}

			this.Invalidate();
		}

		void this_MouseDown(object sender, MouseEventArgs e)
		{
			mMState = MouseEventState.OnDown;
			this.Invalidate();
		}

		void this_MouseLeave(object sender, EventArgs e)
		{
			mMState = MouseEventState.None;
			this.Invalidate();
		}

		void this_MouseHover(object sender, EventArgs e)
		{
			mMState = MouseEventState.OnHover;
		}

		#endregion


		#region ISkinnable Members

		/// <summary>
		/// Use default skin?
		/// </summary>
		[Category("Look && feel")]
		public bool UseDefaultSkin
		{
			get
			{
				return mUseDefaultSkin;
			}
			set
			{
				mUseDefaultSkin = value;
				DefaultLookAndFeel_OnSkinChanged(this, null);
			}
		}

		/// <summary>
		/// Used skin
		/// </summary>
		[Category("Look && feel")]
		public Skin Skin
		{
			get
			{
				if (this.UseDefaultSkin)
				{
					return DefaultLookAndFeel.Skin;
				}

				return mSkin;
			}
			set
			{
				if (this.UseDefaultSkin)
				{
					DefaultLookAndFeel.Skin = value;
				}

				mSkin = value;
				Invalidate();
			}
		}

		#endregion
	}
}
